﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Badger.Vhdl.Types;
using Weazel.Badger.Vhdl.Statements;
using Weazel.Badger.Vhdl.Expressions;
using Weazel.Badger.Vhdl.Operators.Binary;
using Weazel.Badger.Vhdl.Operators.Unary;

#endregion

namespace Weazel.Badger
{
  public class RegisterUpdateProcess
  {
    public static Vhdl.Process Get(RegisterEntity context)
    {
      Vhdl.Process registerUpdateProcess =
        new Weazel.Badger.Vhdl.Process("register_update", context);

      registerUpdateProcess.AddSignalToSensivitityList(context.ClockPort);
      registerUpdateProcess.AddSignalToSensivitityList(context.ResetPort);

      StatementCollection onReset = new StatementCollection();
      StatementCollection onClock = new StatementCollection();

      foreach (VhdlRegister register in context.Registers.Values)
      {
        // first expression (used in the reset block) clears the register
        SequentialStatement clearRegisterStatement =
          new SignalAssignmentStatement(
						register, 
						new ClearSignalExpression(
							onReset,
							register.ReadSignal
						)
					);

        SequentialStatement updateRegisterStatement =
          new SignalAssignmentStatement(
						register, 
						new SignalReferenceExpression(
							onClock,
							register.WriteSignal
						)
					);

        onReset.Add(clearRegisterStatement);
        onClock.Add(updateRegisterStatement);
      }

      registerUpdateProcess.Statements.Add(ProcessSensitivityStatement.Get(context, registerUpdateProcess, onReset, onClock));
      registerUpdateProcess.Resolve(context);

      return registerUpdateProcess;
    }
  }
}
